package com.example.validatestudy.demos.tread.juc;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CompletableFutureTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        /**
         * 创建CompletableFuture
         * new CompletableFuture();
         * CompletableFuture.supplyAsync()
         * CompletableFuture.runAsync()
         */
        CompletableFuture completableFuture1 = new CompletableFuture();
        //completableFuture1.join();

        CompletableFuture<Integer> completableFuture =  CompletableFuture.supplyAsync(()->{
            System.out.println("执行supplyAsync()");
            return 1;
        });
        /**
         * 获取结果
         * get()
         * getNow()
         * join()
         */
        System.out.println("get():"+completableFuture.get());
        System.out.println("getNow():"+completableFuture.getNow(2));

        completableFuture.complete(3);
        System.out.println("complete():"+completableFuture.get());

        /**
         * 流式处理
         * thenApply()
         * thenCombine()
         */
        CompletableFuture<Integer> completableFuture2 =  CompletableFuture.supplyAsync(()->{
            return 1;
        });
        CompletableFuture<Integer> completableFuture3 =  completableFuture2.thenApply(r->{
            return r+1;
        });
        System.out.println("thenApply():"+completableFuture3.join());

        CompletableFuture<Integer> completableFuture4 = completableFuture2.thenCombine(completableFuture3,(r1,r2)->{return r1+r2;});
        System.out.println("thenCombine():"+completableFuture4.get());

        //whenComplete():处理结果和异常
        CompletableFuture<Integer> completableFuture5 = completableFuture2.whenComplete((r,e)->{
            if(e != null){
                System.out.println("e != null");
            }else{
                System.out.println("whenComplete():"+r);
            }
        });

        //handle():处理结果和异常，并返回值 BiFunction
        CompletableFuture<Integer> completableFuture6 = completableFuture2.handle((r,e)->{
            if(e!=null){
                return r+100;
            }else{
                return r+110;
            }
        });
        System.out.println("handle():"+completableFuture6.join());

        CompletableFuture completableFuture7 = CompletableFuture.supplyAsync(()->{
            System.out.println("supplyAsync():11");
            return 11;
        }).thenApply(r ->{
            System.out.println("supplyAsync():22");
            return r+11;
        }).handle((r,e)->{
            if(e == null){
                System.out.println("handle():33");
                return r + 11;
            }
            return r;
        }).whenComplete((r,e)->{
            System.out.println("whenComplete():"+r);
        }).exceptionally(e->{
            e.printStackTrace();
            System.out.println("exceptionally():"+e);
            return null;
        });

        /**
         * 组合处理
         */
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        StringBuffer s = new StringBuffer();
        CompletableFuture cf = CompletableFuture.runAsync(()->{
            s.append("执行线程cf ");
            System.out.println("执行线程cf1");
        },executorService);
        CompletableFuture cf2 = CompletableFuture.runAsync(()->{
            s.append("执行线程cf2 ");
            System.out.println("执行线程cf2");
        },executorService);
        CompletableFuture cf3 = CompletableFuture.runAsync(()->{
            try {
                Thread.sleep(3000);
                s.append("执行线程cf3 ");
                System.out.println("执行线程cf3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },executorService);
        CompletableFuture.allOf(cf,cf2,cf3).thenRun(()->{
            System.out.println("全部执行结束，关闭线程池："+s);
            executorService.shutdown();
        });
        System.out.println(Thread.currentThread().getName()+"--不影响主线程执行");


        CompletableFuture.runAsync(()->{
            try {
                System.out.println(Thread.currentThread().getName()+"--睡眠10秒后执行");
                Thread.sleep(10000);
                completableFuture1.complete(3);//completableFuture1.join()将执行结束
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        completableFuture1.join();
        System.out.println(Thread.currentThread().getName()+"--Over");
    }
}
